﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Galaktika.BI.Charting.PivotChart;
using Galaktika.BI.Extensibility.Dom;
using Galaktika.BI.Runtime.Services;
using Galaktika.BI.Silverlight;
using Galaktika.BI.Silverlight.Controls;
using Galaktika.BI.Silverlight.Controls.PivotGrid;
using Galaktika.BI.Silverlight.Intermediate;
using System.ComponentModel;
using Ranet.AgOlap.Controls.ContextMenu;
using Ranet.AgOlap.Controls.General;
using Galaktika.BI.Silverlight.Charting;
using Galaktika.BI.Silverlight.Controls.Charting;
using Visifire.Charts;

namespace Galaktika.BI.Charting
{
    public class RanetChartSeries : ChartSeries
    {
        //private Border border = null;      
       
        public override string ToString()
        {
            string seriesName = this.AName;

            if (!this.IsSeriesCompatible)
                seriesName = "(incompatible) " + seriesName;

            return seriesName;
        }
                
        new public RanetChart Owner
        {
            get; set;
        }

        #region Private Methods
        private void SetValue(string propertyName, object obj, object value)
        {
            if (obj == null)
            {
                return;
            }

            PropertyInfo propInfo = obj.GetType().GetProperty(propertyName);
            if ((propInfo != null) && (propInfo.CanWrite))
            {
                try
                {
                    propInfo.SetValue(obj, value, null);
                }
                catch
                {
                    throw new Exception(string.Format(Localization.Exc_SetterNotFound, propInfo.Name, obj));
                }
            }
        }

        private object GetValue(string propertyName, object obj)
        {
            if (obj == null)
            {
                return null;
            }

            PropertyInfo propInfo = obj.GetType().GetProperty(propertyName);
            if ((propInfo != null) && (propInfo.CanRead))
            {
                return propInfo.GetValue(obj, null);
            }
            return null;
        }

        // Разбивает строку на элементы, представляющие собой целые числа - индексы
        private int[] ParseFilter(string stringFilter)
        {
            List<int> indexesInFilterResult = new List<int>();

            List<string> filterParts = new List<string>(stringFilter.Trim().Split(','));
            foreach (string filterPart in filterParts)
            {
                indexesInFilterResult.AddRange(this.ParsePartFilter(filterPart));
            }

            return indexesInFilterResult.ToArray();
        }

        // Возвращает диапазон индексов из части фильтра
        private int[] ParsePartFilter(string stringPartFilter)
        {
            List<int> indexesInFilterResult = new List<int>();
            List<string> indexesRange = new List<string>(stringPartFilter.Trim().Split('-'));
            if (indexesRange.Count > 0)
            {
                int indexMin = this.GetMinIndex(indexesRange);
                int indexMax = this.GetMaxIndex(indexesRange);
                for (int indexValue = indexMin; indexValue <= indexMax; indexValue++)
                {
                    indexesInFilterResult.Add(indexValue);
                }
            }
            return indexesInFilterResult.ToArray();
        }

        // Возвращает минимальное целое значение из списка строк indexesRange
        private int GetMinIndex(List<string> indexesRange)
        {
            int indexMinResult = int.MaxValue;
            foreach (string indexString in indexesRange)
            {
                int indexValue = 0;
                if (int.TryParse(indexString, out indexValue))
                {
                    if (indexValue < indexMinResult)
                    {
                        indexMinResult = indexValue;
                    }
                }
            }

            return indexMinResult;
        }

        // Возвращает максимальное целое значение из списка строк indexesRange
        private int GetMaxIndex(List<string> indexesRange)
        {
            int indexMaxResult = int.MinValue;
            foreach (string indexString in indexesRange)
            {
                int indexValue = 0;
                if (int.TryParse(indexString, out indexValue))
                {
                    if (indexValue > indexMaxResult)
                    {
                        indexMaxResult = indexValue;
                    }
                }
            }

            return indexMaxResult;
        }

        #endregion Private Methods

        #region Public Methods

        /// <summary>
        /// Возвращает диаграмму текущей серии
        /// </summary>
        /// <returns></returns>
        //new public T GetDiagram<T>()
        //    where T : DataSeries
        //{
        //    //SeriesViewBase seriesView = SeriesViewFactory.CreateInstance((ViewType)this.AViewType);

        //    DataSeries seriesView = C1ChartSeriesViewHelper.GetView(this.AViewType);
        //    return C1ChartSeriesViewHelper.GetDiagram(seriesView) as T;
        //}

        /// <summary>
        /// Поддерживает ли текущая серия диаграмму targetDiagram
        /// </summary>
        /// <param name="targetDiagram"> Диаграмма, соответствие с которой определяется </param>
        /// <returns></returns>
        //public bool SupportDiagram(DataSeries targetDiagram)
        //{
        //    return C1ChartSeriesViewHelper.SupportDiagram(this, targetDiagram);
        //}

        /// <summary>
        /// Отображение свойств текущей серии на реальную серию графика seriesSource
        /// </summary>
        /// <param name="seriesSource">Реальная серия графика</param>
        /// <returns></returns>
        public  DataSeries GetMappedSeries(DataSeries seriesSource, RanetChart owner)
        {
            this.Owner = owner;
            this.MappedSeies = seriesSource;
            //seriesMapped.Assign(seriesSource);
            //seriesMapped.SynchronizePointOptions = false;
            //seriesMapped = new LineSeries();
            //this.MappedSeies.Name = this.AName;
            //this.MappedSeies.Visibility = System.Windows.Visibility.Visible;
            //this.MappedSeies.Title = this.ALegendText;
           
            if (seriesSource is DataSeries)
            {
                //(this.MappedSeies as BarSeries).ItemsSource = (seriesSource as BarSeries).ItemsSource;
                //(this.MappedSeies as BarSeries).DependentValueBinding = new Binding(this.AValueColumnName);
                //(this.MappedSeies as BarSeries).IndependentValueBinding = new Binding(this.AArgumentColumnName);

                //TODO: Проанализировать какие свойства не одинаковы для различных Series
            }
            // инициализирую созданную серию имеющимися свойствами ChartSeries
            // Series Properties
            //seriesMapped.Name = (seriesSource.Name != string.Empty) ? seriesSource.Name : this.AName;
            //this.SetValue("Visible", seriesMapped, this.AVisible);
            //this.SetValue("ShowInLegend", seriesMapped, this.AShowInLegend);
            //if (this.m_ShowInLegend)
            //{
            //    this.SetValue("LegendText", seriesMapped, this.ALegendText);
            //}

            // View Properties
            //seriesMapped.ChangeView((ViewType)this.AViewType);
            //ViewType viewType = (ViewType)Enum.Parse(typeof(ViewType), this.AViewType.ToString());
            //ViewType viewType = (ViewType)Enum.Parse(typeof(ViewType), this.AViewType2.ToString());
            //ViewType viewType = (ViewType)Enum.Parse(typeof(ViewType), this.AViewType.ToString(),true);
            //seriesMapped.ChangeView(viewType);
            //this.SetValue("Color", seriesMapped.View, this.AViewColor);
            //this.SetValue("ColorEach", seriesMapped.View, this.AViewColorEach);
            //this.SetValue("Transparency", seriesMapped.View, (byte)this.ATransparency);
            //this.SetValue("ExplodeMode", seriesMapped.View, (PieExplodeMode)Enum.Parse(typeof(PieExplodeModeCharting), this.AExplodeModePie));
            //this.SetValue("ExplodedDistancePercentage", seriesMapped.View, this.AExplodedDistancePie);
            //this.SetValue("Depth", seriesMapped.View, this.AViewDepth);

            //// Label Properties
            //this.SetValue("Visible", seriesMapped.Label, this.ALabelVisible);
            //this.SetValue("BackColor", seriesMapped.Label, this.ALabelBackColor);
            //this.SetValue("TextColor", seriesMapped.Label, this.ALabelTextColor);
            //this.SetValue("LineVisible", seriesMapped.Label, this.ALabelLineVisible);
            //this.SetValue("LineColor", seriesMapped.Label, this.ALabelLineColor);
            //this.SetValue("LineLength", seriesMapped.Label, this.ALabelLineLength);
            ////this.SetValue("ValueType", seriesMapped.Label, this.ALabelValueType);
            //this.SetValue("Font", seriesMapped.Label, new Font(this.ALabelFont, FontStyle.Regular));
            //this.SetValue("Antialiasing", seriesMapped.Label, this.ALabelAntialiasing);
            //if (seriesMapped.View is XYDiagramSeriesViewBase)
            //{
            //    this.SetValue("Position", seriesMapped.Label, this.ALabelPosition2D);
            //}

            //// Label.Border Properties
            //this.SetValue("Visible", seriesMapped.Label.Border, this.ALabelBorderVisible);
            //this.SetValue("Color", seriesMapped.Label.Border, this.ALabelBorderColor);
            //this.SetValue("Thickness", seriesMapped.Label.Border, this.ALabelBorderThickness);

            //// PieSeries Properties
            //if (seriesMapped.View is PieSeriesViewBase)
            //{
            //    //((PiePointOptions)seriesMapped.PointOptions).PercentOptions.ValueAsPercent = this.AValueAsPercent;
            //    this.SetValue("Position", seriesMapped.Label, this.ALabelPositionPie);
            //    this.SetValue("HeightToWidthRatio", seriesMapped.View, this.AViewHeightToWidthRatio);
            //    this.SetValue("Rotation", seriesMapped.View, this.AViewRotation);
            //    this.SetValue("SizeAsPercentage", seriesMapped.View, this.AViewSizeAsPercentage);
            //}

            //// PointProperties
            //if (seriesMapped.View is PointSeriesView)
            //{
            //    // LineMarkerOptions
            //    this.SetValue("BorderVisible", ((PointSeriesView)seriesMapped.View).PointMarkerOptions, this.APointMarkerBorderVisible);
            //    this.SetValue("BorderColor", ((PointSeriesView)seriesMapped.View).PointMarkerOptions, this.APointMarkerBorderColor);
            //    this.SetValue("Kind", ((PointSeriesView)seriesMapped.View).PointMarkerOptions, this.APointMarkerKind);
            //    this.SetValue("Size", ((PointSeriesView)seriesMapped.View).PointMarkerOptions, this.APointMarkerSize);
            //}

            //// LineProperties
            //if (seriesMapped.View is LineSeriesView)
            //{
            //    // LineMarkerOptions
            //    this.SetValue("Color", ((LineSeriesView)seriesMapped.View).LineMarkerOptions, this.ALineMarkerColor);
            //    this.SetValue("Visible", ((LineSeriesView)seriesMapped.View).LineMarkerOptions, this.ALineMarkerVisible);
            //    this.SetValue("BorderVisible", ((LineSeriesView)seriesMapped.View).LineMarkerOptions, this.ALineMarkerBorderVisible);
            //    this.SetValue("BorderColor", ((LineSeriesView)seriesMapped.View).LineMarkerOptions, this.ALineMarkerBorderColor);
            //    this.SetValue("Kind", ((LineSeriesView)seriesMapped.View).LineMarkerOptions, this.ALineMarkerKind);
            //    this.SetValue("Size", ((LineSeriesView)seriesMapped.View).LineMarkerOptions, this.ALineMarkerSize);

            //    // LineStyle
            //    this.SetValue("DashStyle", ((LineSeriesView)seriesMapped.View).LineStyle, this.ALineDashStyle);
            //    this.SetValue("Thickness", ((LineSeriesView)seriesMapped.View).LineStyle, this.ALineStyleThickness);
            //}

            //// PointsOptions
            //this.SetValue("PointView", seriesMapped.PointOptions, this.APointView);
            //this.SetValue("Format", seriesMapped.PointOptions.ValueNumericOptions, this.APointsValueFormat);
            //this.SetValue("Precision", seriesMapped.PointOptions.ValueNumericOptions, this.APointsValueFormatPrecision);
            //if (seriesMapped.View is PieSeriesViewBase)
            //{
            //    this.SetValue("ValueAsPercent", ((PiePointOptions)seriesMapped.PointOptions).PercentOptions, this.APointsValueAsPercent);
            //    this.SetValue("ValuePercentPrecision", ((PiePointOptions)seriesMapped.PointOptions).PercentOptions, this.APointsValuePercentPrecision);
            //}

            //// LegendPointsOptions
            //this.SetValue("PointView", seriesMapped.LegendPointOptions, this.ALegendPointView);
            //this.SetValue("Format", seriesMapped.LegendPointOptions.ValueNumericOptions, this.ALegendPointsValueFormat);
            //this.SetValue("Precision", seriesMapped.LegendPointOptions.ValueNumericOptions, this.ALegendPointsValueFormatPrecision);
            //if (seriesMapped.View is PieSeriesViewBase)
            //{
            //    this.SetValue("ValueAsPercent", ((PiePointOptions)seriesMapped.LegendPointOptions).PercentOptions, this.ALegendPointsValueAsPercent);
            //    this.SetValue("ValuePercentPrecision", ((PiePointOptions)seriesMapped.LegendPointOptions).PercentOptions, this.ALegendPointsValuePercentPrecision);
            //}

            //// OverlappingOptions Properties
            //this.SetValue("ResolveOverlapping", seriesMapped.Label.OverlappingOptions, this.AResolveOverlapping);
            //this.SetValue("Indent", seriesMapped.Label.OverlappingOptions, this.AOverlappingIndent);

            return this.MappedSeies;
        }

       
        #endregion Public Methods
       

        new public DataSeries MappedSeies { get; set; }

        public RanetChartSeries()
        {
            ALabelVisible = true;
            ALabelBorderVisible = true;
            ALabelLineVisible = true;
            ALabelAntialiasing = true;
            ALineMarkerVisible = true;
            ALineMarkerBorderVisible = true;
            ALineMarkerKind = MarkerKind.Circle;
            ALineMarkerSize = 10;
            ALineDashStyle = DashStyle.Solid;
            ALineStyleThickness = 2;
            APointMarkerBorderVisible = true;
            APointMarkerKind = MarkerKind.Circle;
            APointMarkerSize = 8;
            AName = string.Empty;
          
        }
                           
      
        //TextBlock Caption_Text = new TextBlock();

        //private void ShowValue()
        //{
        //    //Border border = LayoutRoot;

        //    //StackPanel root = new StackPanel();
        //    //root.VerticalAlignment = VerticalAlignment.Center;
        //    ////            Grid root = new Grid();
        //    //border.Child = root;

        //    //// Значение
        //    //Caption_Text.TextAlignment = TextAlignment.Right;
        //    //Caption_Text.VerticalAlignment = VerticalAlignment.Center;
        //    //Caption_Text.Margin = new Thickness(0, 0, 3, 0);

        //    //if (Cell.CellDescr != null && Cell.CellDescr.Value != null)
        //    //{
        //    //    Caption_Text.Text = Cell.CellDescr.Value.DisplayValue;
        //    //}

        //    //root.Children.Add(Caption_Text);
        //}
        //private void ShowBorder()
        //{
        //    if (IsFocused)
        //    {
        //        border.BorderBrush = new SolidColorBrush(Colors.Black);
        //        border.BorderThickness = new Thickness(1, 1, 1, 1);
        //    }
        //    else
        //    {
        //        border.BorderBrush = new SolidColorBrush(Colors.DarkGray);
        //        border.BorderThickness = new Thickness(0, 0, 1, 1);
        //    }
        //}

        //bool m_IsFocused = false;
        //public bool IsFocused
        //{
        //    set
        //    {
        //        m_IsFocused = value;
        //        ShowBorder();
        //    }
        //    get
        //    {
        //        return m_IsFocused;
        //    }
        //}

      
    }    
}
